
	/***********************************************************************************************

		@API
		Class: jsl.Module inherits jsl.EventMap, jsl.OptionMap

		Constructor:
			obj			jsl.Module 	(id)

		Methods:
			obj			info				(id, value/getter*)
			b				isInfo			(id)
			data		infoData		(id)

		Legend:
			data { id, name, parent, value, getter }

	************************************************************************************************/

	//-------------------------------------------------------------------------------
	jsl.Class("jsl.Module",
		{
			//-------------------------------------------------------------------------------
			inherits: [ jsl.EventMap, jsl.OptionMap ],

			//Private vars
			//-------------------------------------------------------------------------------
			__infos: 	null,
			__mods: 	{},

			//-------------------------------------------------------------------------------
			Module: function(id) {
				//!
				if(arguments.length !== 1) throw jsl.ParamError()
				jsl.validate(id, "qid", "id")
        if(this.__mods[id]) throw jsl.ParamError("AlreadyDefined:id")
        //!

				this.OptionMap()
				this.EventMap()

				this.__name 		= id
				this.__infos 		= []
				this.__mods[id]	= true
			},
      //-------------------------------------------------------------------------------
			info: function(id, value) {
				var parent, pid, name, i, f, v, cs//!
				if(!arguments.length || arguments.length > 2) throw jsl.ParamError()
				jsl.validate(id, "qid", "id")//!

				//1-info definition
				if(arguments.length === 2) {//!
					if(this.__infos["i_" + id])	throw jsl.ParamError("AlreadyDefined:id")//!

					if(id.indexOf(".") !== -1) {
						pid  		= id.slice(0, id.lastIndexOf("."))
	          name    = id.slice(id.lastIndexOf(".") + 1)
						parent	= this.__infos["i_" + pid]

						//!
	          if(!parent)                    							throw jsl.ParamError("NotDefined: id(parent-id)")
	          if(!jsl.isObject(this.__infos["i_" + pid]))	throw jsl.ParamError("BadType:    id(parent-id):object")//!
					}
	        else
	          name = id

	        f = jsl.isFunction(value)
					i =	{
						id: 		id 		+ "" 	,
	          name:   name  + ""  ,
	          parent: parent || null,
						getter:	f ? value : null,
						value: 	f ? null	: (arguments.length === 2 ? value : {}),
						childs:	[]
					}

					this.__infos["i_" + id] = i
					this.__infos.push(i)
					if(parent) parent.childs.push(i)

					v = this
				}

				//2-info reading
				else {

					i = this.__infos["i_" + id]//!
					if(!i)	throw jsl.ParamError("NotDefined:id")//!

					try 			{	v = i.getter ? i.getter.call(this, id) : i.value }
					catch(e)	{ throw jsl.ScriptError("BadScript:getter", e)	}

					cs = i.childs//!
	        if(cs.length && !jsl.isObject(v)) throw jsl.Error("BadReturnType:Object")//!

					for(var a = 0; a < cs.length; a++)
						v[cs[a].name] = this.info(cs[a].id)
				}

				return v
			},
			//-------------------------------------------------------------------------------
			isInfo: function(id) {//!
				if(arguments.length !== 1)	throw jsl.ParamError()
				jsl.validate(id, "s+", "id")//!

				return !!this.__infos["i_" + id]
			},
		  //-------------------------------------------------------------------------------
	 		infoData: function(id) {
	 			var i
				//!
				if(arguments.length !== 1)		throw jsl.ParamError()
				jsl.validate(id, "s+", "id")//!

				i = this.__infos["i_" + id]//!
				if(!i)	throw jsl.ParamError("NotDefined:id")//!

				return  {
                  id:     i.id     		,
                  name:   i.name   		,
                  value:  i.value  		,
                  getter: i.getter  	,
                  parent: i.parent ? i.parent.id : null
                }
	 		}
		})
